﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Management;
using System.Collections;
// namespaces necesarios para conexión a bd
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Persistencia_y_capa_de_negocio
{
    public class CADReporte
    {
        private static readonly CADReporte instancia = new CADReporte();
        public static CADReporte Instancia
        {
            get { return instancia; }
        }

        // Cadena de conexión.
        private string cadCon;
        private SqlDataAdapter da;
        private SqlDataAdapter daa;
        private SqlDataAdapter daaa;
        private SqlConnection c;
        private DataSet vdb;

        /// <summary>
        /// Constructor.
        /// </summary>
        public CADReporte()
        {
            try
            {
                // Establecemos la cadena de conexión desde app.config.
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;

                // Creamos la base de datos virtual.
                vdb = new DataSet();

                // Obtenemos una conexión.
                c = new SqlConnection(cadCon);

                // Almacenamos la base de datos en local.
                da = new SqlDataAdapter("select * from reporte", c);
                da.Fill(vdb, "Reporte");

                daa = new SqlDataAdapter("select * from usuarios", c);
                daa.Fill(vdb, "Usuario");

                daaa = new SqlDataAdapter("select * from escuadron", c);
                daaa.Fill(vdb, "Escuadron");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Insertamos en la base de datos un reporte
        /// </summary>
        /// <param name="re">Variable con los datos necesarios que contiene un reporte.</param>
        public bool InsertarReporte(ENReporte re)
        {
            // Indica si se ha realizado la inserción.
            bool insertado = false;
            DataRow r = null;
            // Obtenemos la tabla reporte.
            DataTable t = new DataTable();
            t = vdb.Tables["Reporte"];

            try
            {
                // Comprobamos si ya existe un reporte con esa fecha.
                r = t.Select("fecha = \'" + re.Fecha + "\'")[0];

                // Actualizamos la información del reporte.
                r["fecha"] = re.Fecha;
                r["atacante"] = re.Atacante;
                r["defensor"] = re.Defensor;
                r["ganador"] = re.Ganador;
                r["ataqueA"] = re.AtaqueA;
                r["defensaA"] = re.DefensaA;
                r["ataqueD"] = re.AtaqueD;
                r["defensaD"] = re.DefensaD;
                r["texto"] = re.Texto;

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Reporte");
            }
            catch
            {
                // Significa que el resultado ha sido null. O sea que hay que insertar, no modificar.
                r = t.NewRow();

                // Insertamos los valores del nuevo reporte.
                r["fecha"] = re.Fecha;
                r["atacante"] = re.Atacante;
                r["defensor"] = re.Defensor;
                r["ganador"] = re.Ganador;
                r["ataqueA"] = re.AtaqueA;
                r["defensaA"] = re.DefensaA;
                r["ataqueD"] = re.AtaqueD;
                r["defensaD"] = re.DefensaD;
                r["texto"] = re.Texto;

                // Añadimos la nueva fila a la tabla virtual.
                t.Rows.Add(r);
                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Reporte");

                // Se ha realizado la inserción.
                insertado = true;

                // Establecemos la cadena de conexión desde app.config.
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;

                // Creamos la base de datos virtual.
                vdb = new DataSet();

                // Obtenemos una conexión.
                c = new SqlConnection(cadCon);

                // Almacenamos la base de datos en local.
                da = new SqlDataAdapter("select * from reporte", c);
                da.Fill(vdb, "Reporte");

                daa = new SqlDataAdapter("select * from usuarios", c);
                daa.Fill(vdb, "Usuario");

                daaa = new SqlDataAdapter("select * from escuadron", c);
                daaa.Fill(vdb, "Escuadron");
            }

            // Devolvemos el resultado.
            return insertado;
        }

        /// <summary>
        /// Recoje de la base de datos los reportes.
        /// </summary>
        /// <returns> Devuelve un ArrayList con los datos de todas los reportes.</returns>
        public ArrayList getReportes()
        {
            // ArrayList de reportes.
            ArrayList lista = new ArrayList();

            // Obtenemos la tabla reportes.
            DataTable t = new DataTable();
            t = vdb.Tables["Reporte"];

            // Extraemos los ENReporte de cada fila de la base de datos.
            foreach (DataRow r in t.Rows)
            {
                ENReporte re = new ENReporte();

                // Insertamos los datos
                re.Fecha = r["fecha"].ToString().Trim();
                re.Atacante = Convert.ToInt32(r["atacante"]);
                re.Defensor = Convert.ToInt32(r["defensor"]);
                re.Ganador = Convert.ToInt32(r["ganador"]);
                re.AtaqueA = Convert.ToInt32(r["ataqueA"]);
                re.DefensaA = Convert.ToInt32(r["defensaA"]);
                re.AtaqueD = Convert.ToInt32(r["ataqueD"]);
                re.DefensaD = Convert.ToInt32(r["defensaD"]);
                re.Texto = r["texto"].ToString().Trim();

                DataRow rr;

                DataTable te = new DataTable();
                te = vdb.Tables["Escuadron"];
                DataTable tu = new DataTable();
                tu = vdb.Tables["Usuario"];

                rr = te.Select("id = \'" + re.Atacante + "\'")[0];
                rr = tu.Select("id = \'" + rr["usuario"].ToString().Trim() + "\'")[0];
                re.NAtacante = rr["cuenta"].ToString().Trim();

                rr = tu.Select("id = \'" + re.Defensor + "\'")[0];
                re.NDefensor = rr["cuenta"].ToString().Trim();

                rr = tu.Select("id = \'" + re.Ganador + "\'")[0];
                re.NGanador = rr["cuenta"].ToString().Trim();

                lista.Add(re);
            }

            // Devolvemos el resultado.
            return lista;
        }

        /// <summary>
        /// Devuelve un reporte
        /// </summary>
        /// <param name="nombre">Fecha reporte</param>
        /// <returns>Devuelve un ENReporte</returns>
        public ENReporte getReporte(string fecha)
        {
            // Obtenemos la tabla reporte.
            DataTable t = new DataTable();
            t = vdb.Tables["Reporte"];

            try
            {
                // Comprobamos si existe un reporte con esa fecha.
                DataRow r = t.Select("fecha = \'" + fecha + "\'")[0];

                // Creamos el reporte.
                ENReporte re = new ENReporte();
                re.Fecha = r["fecha"].ToString().Trim();
                re.Atacante = Convert.ToInt32(r["atacante"]);
                re.Defensor = Convert.ToInt32(r["defensor"]);
                re.Ganador = Convert.ToInt32(r["ganador"]);
                re.AtaqueA = Convert.ToInt32(r["ataqueA"]);
                re.DefensaA = Convert.ToInt32(r["defensaA"]);
                re.AtaqueD = Convert.ToInt32(r["ataqueD"]);
                re.DefensaD = Convert.ToInt32(r["defensaD"]);
                re.Texto = r["texto"].ToString().Trim();

                DataRow rr;

                DataTable te = new DataTable();
                te = vdb.Tables["Escuadron"];
                DataTable tu = new DataTable();
                tu = vdb.Tables["Usuario"];

                rr = te.Select("id = \'" + re.Atacante + "\'")[0];
                rr = tu.Select("id = \'" + rr["usuario"].ToString().Trim() + "\'")[0];
                re.NAtacante = rr["cuenta"].ToString().Trim();

                rr = tu.Select("id = \'" + re.Defensor + "\'")[0];
                re.NDefensor = rr["cuenta"].ToString().Trim();

                rr = tu.Select("id = \'" + re.Ganador + "\'")[0];
                re.NGanador = rr["cuenta"].ToString().Trim();

                // Devolvemos el resultado.
                return re;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Elimina un reporte de la base de datos.
        /// </summary>
        /// <param name="nombre">fecha del reporte que se va a eliminar.</param>
        public void EliminaReporte(string fecha)
        {
            // Obtenemos la tabla reporte.
            DataTable t = vdb.Tables["Reporte"];

            try
            {
                // Comprobamos si existe un reporte con esa fecha.
                DataRow r = t.Select("fecha = \'" + fecha + "\'")[0];

                // La eliminamos de la base de datos.
                r.Delete();
                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Reporte");
            }
            catch
            {
                // Mostrar un error.
            }
        }

        /// <summary>
        /// Función que devuelve un arrayList de reportes mediante criterios de búsqueda
        /// </summary>
        /// <param name="fecha">fecha reporte</param>
        /// <param name="atacante">atacante</param>
        /// <param name="defensor">defensor</param>
        /// <param name="ganador">ganador</param>
        /// <param name="descripcion">descripcion batalla</param>
        /// <returns></returns>
        public ArrayList getReporteBuscar(string atacante, string defensor, string ganador, string ataqueA, string defensaA, string ataqueD, string defensaD, string descripcion)
        {
            DataTable t = vdb.Tables["Reporte"];
            string select = "";
            ArrayList lista = new ArrayList();

            DataRow rr, rrr;
            DataTable te = new DataTable();
            te = vdb.Tables["Escuadron"];
            DataTable tu = new DataTable();
            tu = vdb.Tables["Usuario"];

            try
            {
                if (atacante != "")
                {
                    rr = tu.Select("cuenta = \'" + atacante + "\'")[0];
                    rrr = te.Select("usuario = \'" + rr["id"] + "\'")[0];
                    atacante = rrr["id"].ToString().Trim();

                    select += "atacante = " + atacante + " ";
                }
                if (defensor != "")
                {
                    rr = tu.Select("cuenta = \'" + defensor + "\'")[0];
                    defensor = rr["id"].ToString().Trim();

                    if (atacante != "")
                    {
                        select += " and ";
                    }
                    select += "defensor = " + defensor + " ";
                }
                if (ganador != "")
                {
                    rr = tu.Select("cuenta = \'" + ganador + "\'")[0];
                    ganador = rr["id"].ToString().Trim();

                    if (atacante != "" || defensor != "")
                    {
                        select += " and ";
                    }
                    select += "ganador = " + ganador + " ";
                }
                if (ataqueA != "")
                {
                    if (atacante != "" || defensor != "" || ganador != "")
                    {
                        select += " and ";
                    }
                    select += "ataqueA = " + ataqueA + " ";
                }
                if (defensaA != "")
                {
                    if (atacante != "" || defensor != "" || ganador != "" || ataqueA != "")
                    {
                        select += " and ";
                    }
                    select += "defensaA = " + defensaA + " ";
                }
                if (ataqueD != "")
                {
                    if (atacante != "" || defensor != "" || ganador != "" || ataqueA != "" || defensaA != "")
                    {
                        select += " and ";
                    }
                    select += "ataqueD = " + ataqueD + " ";
                }
                if (defensaD != "")
                {
                    if (atacante != "" || defensor != "" || ganador != "" || ataqueA != "" || defensaA != "" || ataqueD != "")
                    {
                        select += " and ";
                    }
                    select += "defensaD = " + defensaD + " ";
                }
                if (descripcion != "")
                {
                    if (atacante != "" || defensor != "" || ganador != "" || ataqueA != "" || defensaA != "" || ataqueD != "" || defensaD != "")
                    {
                        select += " and ";
                    }
                    select += "texto like \'%" + descripcion + "%\' ";
                }

                foreach (DataRow r in t.Select(select))
                {
                    ENReporte re = CADReporte.Instancia.getReporte(r["fecha"].ToString());
                    lista.Add(re);
                }
            }

            catch
            {
                MessageBox.Show("Datos incorrectos, Vuelva a introducirlos.", "Datos Incorrectos", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            }

            return lista;
        }

    }
}
